package com.billard.utils;

import com.billard.properties.JwtProperties;
import com.billard.result.Result;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Map;

/**
 * 拦截器校验jwt
 */
@Slf4j
@Component
public class JwtTokenInterceptorUtil implements HandlerInterceptor {

    @Autowired
    private JwtProperties jwtProperties;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 放行 OPTIONS 请求（用于 CORS 预检）
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            return true;
        }

        log.info("JWT验证开启, handler: {}", handler);

        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        String tokenName = jwtProperties.getTokenName();
        String token = request.getHeader(tokenName);

        if (token == null || token.isEmpty()) {
            log.warn("请求头中未包含 {}，拒绝访问", tokenName);
            response.setStatus(401);
            response.setContentType("application/json;charset=UTF-8");
            Result<Void> result = Result.error(401, "未提供认证令牌");
            response.getWriter().write(new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(result));
            return false;
        }
        // 去除 Bearer 前缀
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
        }
        try {
            log.info("开始校验JWT: {}", token);
            Map<String, Object> claims = JwtUtil.parseJWT(jwtProperties.getSecretKey(), token);
            Long userId = Long.valueOf(claims.get("id").toString());
            // 存入上下文，供后续使用
            UserIdUtil.setUserId(userId);
            log.info("JWT校验成功，当前用户ID: {}", UserIdUtil.getUserId());
            return true;

        } catch (Exception e) {
            log.warn("token过期，拒绝访问");
            response.setStatus(401);
            response.setContentType("application/json;charset=UTF-8");
            Result<Void> result = Result.error(401, "令牌无效或已过期");
            response.getWriter().write(new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(result));
            return false;
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 清理 ThreadLocal，防止内存泄漏
        UserIdUtil.remove();
    }
}